package cn.huaqingcheng.tianshu.common.core;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.Unmodifiable;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * ListTool
 */
public interface ListTool {


    static boolean isNotEmpty(Collection<?> collection) {
        return !isEmpty(collection);
    }

    static boolean isEmpty(Collection<?> collection) {
        return collection == null || collection.isEmpty();
    }

    @Unmodifiable
    static <E, R> List<? extends R> map(@Nullable Collection<E> collection, @NotNull Function<? super E, ? extends R> mapper) {
        if (collection == null) {
            return List.of();
        }
        return collection.stream()
                .map(mapper)
                .toList();
    }

    @Unmodifiable
    static <E, T, K, R> Map<K, R> mapToMap(
            @Nullable Collection<? extends E> collection,
            @NotNull Function<? super E, ? extends T> map,
            @NotNull Function<? super T, ? extends K> keyMap,
            @NotNull Function<? super T, ? extends R> valueMap
    ) {
        return collection == null
               ? Map.of()
               : collection.stream()
                       .map(map)
                       .collect(Collectors.toMap(keyMap, valueMap));
    }

    @Unmodifiable
    static <E, K, R> Map<K, R> toMap(
            @Nullable Collection<? extends E> collection,
            @NotNull Function<? super E, ? extends K> keyMap,
            @NotNull Function<? super E, ? extends R> valueMap
    ) {
        return collection == null
               ? Map.of()
               : collection.stream()
                       .collect(Collectors.toMap(keyMap, valueMap));
    }

    @Unmodifiable
    static <E, K> Map<K, E> toMap(
            @Nullable Collection<? extends E> collection,
            @NotNull Function<? super E, ? extends K> keyMap
    ) {
        return collection == null
               ? Map.of()
               : collection.stream()
                       .collect(Collectors.toMap(keyMap, Function.identity()));
    }

}
